import torch

"""
张量tensor，类似于Numpy的ndarray，是pytorch框架运算的基本单元，
具有多维性、能存储不同类型的数据，并且通过.to(设备)可以在
CPU和GPU之间转换，通过requirs_grad=True开启自动梯度计算。
"""

# 1. 创建张量--------------------------------------------------
print(torch.tensor(666))
print(torch.tensor([11, 22, 33]))
print(torch.tensor([[1, 2], [3, 4]]))
print(torch.empty(3))   # 创建size=3的空张量，值为随机值可能为0也可能是垃圾值
print(torch.empty((2, 3))) # size=(2, 3)
print(torch.zeros(1, 2))    # 全0数组
print(torch.ones(2, 3))
torch.manual_seed(100)      # 随机数种子，作用是【复现】
print(torch.rand(2, 1))     # 返回一个由区间[0,1)上均匀分布的随机数填充的张量
print(torch.randn(2, 3))    # 返回一个张量，其中充满来自均值为0，方差为1的正态分布（也称为标准正态分布）的随机数
print(torch.normal(mean=-1, std=2, size=(2,3)))   # 生成指定均值和标准差的正态分布随机数


# 2. 数据类型----------------------------------------------------
t = torch.ones(2, 3)
print(t.dtype)      # torch.float32
t = torch.ones(2, 3, dtype=torch.int8)
print(t.dtype)      # torch.int8
t = t.float()
print(t.dtype)      # torch.float32
t = t.to(torch.int16)
print(t.dtype)      # torch.int16


# 3. 访问张量------------------------------------------------------
t = torch.tensor([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
])
# 通过下标索引、切片
print(t[0])     # tensor([1, 2, 3])
print(t[0, 2])  # tensor(3)
''''
numpy(张量)   以NumPy数组的形式返回张量。
item(张量)    将此张量的值作为标准Python数字返回。这只适用于只有一个元素的张量。
'''
print(t[0, 2].numpy())  # 3     <class 'numpy.ndarray'>
print(t[0, 2].item())   # 3     <class 'int'>
print(t[0:2])           # tensor([[1, 2, 3],[4, 5, 6]])
print(t[:, 1:3])        # tensor([[ 2,  3],[ 5,  6],[ 8,  9],[11, 12]])

# 4. 修改形状---------------------------------------------------------
'''
reshape()和view()都可以改变形状，但是要具有相同数据和数量。
区别：view()改变形状之后内存不会重新分配，一般来说我们优先选用reshape
>>> a = torch. randn(1, 2, 3, 4)
>>> a. size()
torch. Size([1, 2, 3, 4])
>>> b = a. transpose(1, 2)  # 交换二维和三维空间
>>> b. size()
torch. Size([1, 3, 2, 4])
>>> c = a. view(1, 3, 2, 4)  # 不改变张量在内存中的布局
>>> c. size()
torch. Size([1, 3, 2, 4])
>>> torch. equal(b, c)
False
'''
t = torch.arange(12)
print(t.shape)      # torch.Size([12])
print(t.reshape(2, 6).shape)    # torch.Size([2, 6])
print(t.reshape(-1, 3).shape)   # -1会自动计算某个维度的大小    torch.Size([4, 3])
print(t.reshape(-1, 2, 3).shape)    # torch.Size([2, 2, 3])
print(t.view(-1, 6).size())     # torch.Size([2, 6])
